using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using OrmTestDomain;
using ShellProgressBar;

namespace FreeSqlTest.BackgroundServices;

public class FreeSqlTableSplitTestService(ILogger<FreeSqlDefaultTestService> logger, IFreeSql freeSql)
    : BackgroundService
{
    private readonly IFreeSql _freeSql = freeSql;
    private readonly ILogger<FreeSqlDefaultTestService> _logger = logger;


    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        var testList = PrepareTestData();
        var baseTable = _freeSql.CodeFirst.GetTableByEntity(typeof(UserEntity));
        var asTableImpl = _freeSql.CodeFirst.GetTableByEntity(typeof(UserSplitEntity)).AsTableImpl
            .SetTableName(0, baseTable.DbName);
        //未设置时间条件时，只命中最新的 3个分表：
        _freeSql.CodeFirst.GetTableByEntity(typeof(UserSplitEntity)).AsTableImpl
            .SetDefaultAllTables(value => value.Take(2).ToArray());
        Insert(testList);
        Update(testList);
        Delete(testList);

        return Task.CompletedTask;
    }

    private IList<UserSplitEntity> PrepareTestData()
    {
        var result = new List<UserSplitEntity>();
        var random = new Random();
        var randomNumber = random.Next(100, 200);
        var totalTicks = randomNumber;

        var progressBarOptions = new ProgressBarOptions { ProgressCharacter = '─', ProgressBarOnBottom = true };
        using (var bar = new ProgressBar(totalTicks, "Test Data Preparing....", progressBarOptions))
        {
            for (var i = 1; i <= totalTicks; i++)
            {
                result.Add(new UserSplitEntity { CreateTime = DateTime.Now.AddDays(1) });
                result.Add(new UserSplitEntity { CreateTime = DateTime.Now.AddDays(-2) });
                result.Add(new UserSplitEntity { CreateTime = DateTime.Now });
                bar.Tick($" {i} of {totalTicks}");
            }
        }

        return result;
    }


    public void BulkInsert(IList<UserSplitEntity> list)
    {
        // _freeSql.InsertOrUpdate<UserSplitEntity>().AsTable().SetSource(list).ExecuteSqlBulkCopy();
    }


    private void Insert(IList<UserSplitEntity> list)
    {
        var totalTicks = list.Count;

        var progressBarOptions = new ProgressBarOptions { ProgressCharacter = '─', ProgressBarOnBottom = true };
        using (var bar = new ProgressBar(totalTicks, "Test Data Inserting....", progressBarOptions))
        {
            var i = 1;
            foreach (var item in list)
            {
                _freeSql.Insert(item).ExecuteAffrows();
                bar.Tick($" {i} of {totalTicks}");
                i++;
            }
        }
    }

    public void Delete(IList<UserSplitEntity> list)
    {
        var totalTicks = list.Count;

        var progressBarOptions = new ProgressBarOptions { ProgressCharacter = '─', ProgressBarOnBottom = true };
        using (var bar = new ProgressBar(totalTicks, "Test Data Deleting....", progressBarOptions))
        {
            var i = 1;
            foreach (var item in list)
            {

                var delete = _freeSql.Delete<UserSplitEntity>(item);
                var sql =delete.ToSql();
                delete.ExecuteAffrows();

                bar.Tick($" {i} of {totalTicks}");
                i++;
            }
        }
    }

    public void Update(IList<UserSplitEntity> list)
    {
        var totalTicks = list.Count;

        var progressBarOptions = new ProgressBarOptions { ProgressCharacter = '─', ProgressBarOnBottom = true };
        using (var bar = new ProgressBar(totalTicks, "Test Data Updating....", progressBarOptions))
        {
            var i = 1;
            foreach (var item in list)
            {
                item.Name = DateTime.Now.ToLongTimeString();
                var update = _freeSql.Update<UserSplitEntity>().SetSource(item);
                var sql =update.ToSql();
                update.ExecuteAffrows();

                bar.Tick($" {i} of {totalTicks}");
                i++;
            }
        }
    }


    public void Find()
    {
        var tableName = _freeSql.CodeFirst.GetTableByEntity(typeof(UserSplitEntity))
            .AsTableImpl
            .GetTableNameByColumnValue(DateTime.Parse("2023-12-16"), true);
        var sql = _freeSql.Select<UserSplitEntity>().ToSql();
        var list = _freeSql.Select<UserSplitEntity>().ToList<UserSplitEntity>();
        Console.WriteLine(list.Count);
    }
}
